package cn.demoncat.util.mybatis.plus;

import cn.demoncat.util.lang.ReflectFieldUtil;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.enums.SqlLike;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;

import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 查询条件，支持lambda
 *
 * @author 延晓磊
 * @since 2023年08月31日
 */
public class LambdaQuery<T> extends LambdaQueryWrapper<T> {

    /**
     * 默认构造
     */
    public LambdaQuery() {
        super();
    }

    /**
     * 重写构造，用于 lambda() 生成
     */
    LambdaQuery(T entity, Class<T> entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq,
                       Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias,
                       SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
        super.setEntity(entity);
        super.setEntityClass(entityClass);
        this.paramNameSeq = paramNameSeq;
        this.paramNameValuePairs = paramNameValuePairs;
        this.expression = mergeSegments;
        this.paramAlias = paramAlias;
        this.lastSql = lastSql;
        this.sqlComment = sqlComment;
        this.sqlFirst = sqlFirst;
        ReflectFieldUtil.set(this, "sqlSelect", sqlSelect);
    }


    /**
     * eq 条件
     *
     * @param column
     * @param val   为空时忽略，判断空须使用isEmpty或isNullEmpty
     * @return
     */
    @Override
    public LambdaQuery<T> eq(SFunction<T,?> column, Object val) {
        return this.eq(true, column, val);
    }

    /**
     * eq 条件
     *
     * @param condition
     * @param column
     * @param val   为空时忽略，判断空须使用isEmpty或isNullEmpty
     * @return
     */
    @Override
    public LambdaQuery<T> eq(boolean condition, SFunction<T,?> column, Object val) {
        super.eq(condition, column, val);
        return this;
    }

    /**
     * like 条件
     *
     * @param column
     * @param val       为空时忽略
     * @return '%值%'
     */
    @Override
    public LambdaQuery<T> like(SFunction<T,?> column, Object val) {
        return this.like(true, column, val);
    }

    /**
     * like 条件
     *
     * @param condition
     * @param column
     * @param val       为空时忽略
     * @return '%值%'
     */
    @Override
    public LambdaQuery<T> like(boolean condition, SFunction<T,?> column, Object val) {
        super.like(condition, column, val);
        return this;
    }

    /**
     * like 条件
     *
     * @param column
     * @param val       为空时忽略
     * @return '值%'
     */
    @Override
    public LambdaQuery<T> likeLeft(SFunction<T,?> column, Object val) {
        return this.likeLeft(true, column, val);
    }

    /**
     * like 条件
     *
     * @param condition
     * @param column
     * @param val       为空时忽略
     * @return '值%'
     */
    @Override
    public LambdaQuery<T> likeLeft(boolean condition, SFunction<T,?> column, Object val) {
        super.likeRight(condition, column, val);
        return this;
    }

    /**
     * like 条件
     *
     * @param column
     * @param val       为空时忽略
     * @return '%值'
     */
    @Override
    public LambdaQuery<T> likeRight(SFunction<T,?> column, Object val) {
        return this.likeRight(true, column, val);
    }

    /**
     * like 条件
     *
     * @param condition
     * @param column
     * @param val       为空时忽略
     * @return '%值'
     */
    @Override
    public LambdaQuery<T> likeRight(boolean condition, SFunction<T,?> column, Object val) {
        super.likeLeft(condition, column, val);
        return this;
    }







    /**
     * eq 条件
     *
     * @param condition
     * @param column
     * @param sqlKeyword
     * @param val   为空时忽略，判断空须使用super.addCondition()
     * @return
     */
    @Override
    protected LambdaQuery<T> addCondition(boolean condition, SFunction<T,?> column, SqlKeyword sqlKeyword, Object val) {
        if (condition && condition(val)) {
            super.addCondition(true, column, sqlKeyword, val);
        }
        return this;
    }

    /**
     * like 条件
     *
     * @param condition
     * @param keyword
     * @param column
     * @param val       为空时忽略
     * @param sqlLike
     * @return
     */
    @Override
    protected LambdaQuery<T> likeValue(boolean condition, SqlKeyword keyword, SFunction<T,?> column, Object val, SqlLike sqlLike) {
        if (condition && condition(val)) {
            super.likeValue(true, keyword, column, val, sqlLike);
        }
        return this;
    }

    /**
     * 条件处理
     *
     * @param val   如果为null或''
     * @return
     */
    private static boolean condition(Object val){
        if (val == null) {
            return false;
        }
        return !(val instanceof String) || !((String) val).isEmpty();
    }
}
